home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-05-07 | 24.6 KB | 810 lines | [TEXT/MPS ] |
- ;*********************** File: SCSI.a *************************
- ;**************************************************************
- ;
- ; This file contains all the items in the SCSI menu. It also
- ; contains the SCSI primatives for comunication with SCSI hard
- ; disks.
- ;
- ; Note: All the symbols that are declared or imported before
- ; start of the first module (PROC, MAIN or RECORD) are defined
- ; for all modules in this file. Forward references to other
- ; modules in a file must be imported.
-
- INCLUDE 'FormatEqu.a'
- LOAD 'Traps.d'
- LOAD 'ToolEqu.d'
- LOAD 'SysEqu.d'
- LOAD 'QuickEqu.d'
- LOAD 'SCSIEqu.d'
-
- EXPORT (Res,Last_Cmd,CompStat,CompMsg):DATA
- EXPORT (BadB_Num):DATA
-
- Addr ds.w 1 ;address of hard disk
- Heads ds.l 1 ;number of heads on hard disk
- Cyls ds.l 1 ;number of cylinders on hard disk
- WrtPreComp ds.l 1 ;cylinder to start write precompensation
- RedWrtCur ds.l 1 ;cylinder to start reduced write current
- Interleave ds.w 1 ;interleave number to be used
- StepCode ds.w 1 ;type of step pulse used
-
- CompStat ds.w 1 ;status from _SCSIComplete
- CompMsg ds.w 1 ;message from _SCSIComplete
-
- Res ds.w 1 ;result from SCSI commands
- Last_Cmd ds.w 1 ;last command executed
-
- BadB_Num ds.l 1 ;total number of bad blocks
- IMPORT (DialogPort,ItemType,ItemHandle,ItemRect):DATA
- IMPORT (EventLoop,DefButton,RadioHiLite):CODE
- IMPORT (CountOff,ExtractNumb,SortBuff,OutBuff):CODE
- IMPORT (ErrorProc,ClearBuff):CODE
- IMPORT (DialogBuff,ButtonHit):DATA
- IMPORT (StrBuff1,StrBuff2,StrBuff3,StrBuff4):DATA
-
- Buffers RECORD EXPORT
- EXPORT (CommandBuff,PseudoProg,ParamBuff):DATA
- EXPORT (BadB_List,BadB_Out):DATA
- ALIGN 2
-
- CommandBuff ds.b CBuffLen ;buffer for SCSI commands
- PseudoProg ds.b PProgLen ;buffer for pseudo program
- ParamBuff ds.b ParamBuffLen ;buffer for parameters
- BadB_List ds.l MaxBBListLen ;buffer area for entering and
- ;sorting bad blocks
- BadB_Out ds.l MaxBBOutLen ;buffer area for output to
- ;to the disk drive
-
- ENDR
-
- ; PROC SelAddrProc
- ;
- ; This procedure gets the address of the device to be formatted
- ; from the user. It then tests to see if the device is connected
- ; and if the device is ready to be formatted. If either of these
- ; are false, it jumps to ErrorProc (error handling procedure).
-
- SelAddrProc PROC EXPORT
- IMPORT (Hd_Select,HD_TestUnit,HD_Discon):CODE
- IMPORT (UnHiLite,ResetDisk):CODE
-
- clr.l -(A7) ;space for pointer to dialog
- move.w #SelAddrRN,-(A7) ;select address dialog resource#
- pea DialogBuff(A5) ;push pointer to dialog storage
- move.l #-1,-(A7) ;make dialog top most window
- _GetNewDialog
-
- move.l (A7),DialogPort(A5) ;save pointer to dialog and
- ;leave a copy on the stack the
- ;for call to _SetPort
- _SetPort
- lea DialogBuff(A5),A4 ;pass address of dialog record
- jsr DefButton ;make default = "Select" button
-
- move.w #10,D0 ;make Mac's address grey
- jsr UnHiLite
-
- ; Register ussage:
- ; D0 Radio button that was selected, now must be unselected
- ; D1 Radio button that was just clicked on; to be selected
-
- ; Initialize D0 and D3 for first call to RadioHiLite. D0=0
- ; is flag for no radio button to deselect. D1=3 is to set the
- ; default SCSI address = 0.
- clr.l D0
- moveq.l #3,D7
-
-
- NotYet
- move.w D7,D1 ;update D1 (pass to RadioHiLite)
- jsr RadioHiLite ;change radio button selected
- clr.l -(A7) ;use standard filter proc function
- pea ButtonHit(A5)
- _ModalDialog
- cmpi.w #2,ButtonHit(A5) ;was select or cancel button hit
- ble EndDialog ;yes, so close up dialog
- move.l D7,D0 ;D0 = id of old radio button
- move.w ButtonHit(A5),D7 ;D7 = id of new radio button
- bra.s NotYet ;loop back for next mouse down
-
- EndDialog
- move.l DialogPort(A5),-(A7) ;pass address of Dialog Rec
- _CloseDialog ;close dialog
-
- cmpi.w #2,ButtonHit(A5) ;was ok button hit
- blt Continue ;yes
- jmp EventLoop ;no, go get next event
-
- Continue
- subq.w #3,D7 ;D7 = last radio button hit, so
- ;subtract item # for radio
- ;button "0"
- move.w D7,Addr(A5) ;D7 now equals address selected
-
- jsr ResetDisk ;reset SCSI bus
- tst.w Res(A5) ;did we succeed
- bne ToErrorProc ;no, go handle error
-
- ; This next block of code, though the end of this procedure, is
- ; an example of how all SCSI commands are done. You can replace
- ; the SCSI command Test Unit Ready with any other SCSI command.
- ; The Mode Select and Format Unit commands used in FormatProc
- ; differ only in that data is transfered after the command.
-
-
- ; First we get control of the bus and select the target device.
- jsr HD_Select ;go get control of bus and
- ;select device
- tst.w Res(A5) ;did we succeed
- bne ToErrorProc ;no, go handle error
-
- ; Second, we clear the buffer we use to construct the SCSI
- ; command in.
- lea CommandBuff(A5),A0 ;pass address of buffer in A0
- move.l #CBuffLen,D0 ;pass buffer size in D0
- jsr ClearBuff ;clear buffer
-
- ; Third, we construct the command. This one has no parameters
- ; in the CDB (Command Desciption Block), so we only have to move
- ; the SCSI OP code into the CDB.
-
- move.b #TestUReady,CommandBuff(A5) ;move OP code into byte
- ;1 of the CDB
- clr.w -(A7) ;clear space for trap result
- pea CommandBuff(A5) ;pass address of CDB
- move.w #CommLenS,-(A7) ;pass length of command. This is
- ;a class 0 SCSI command, so
- ;the length is 6 bytes.
-
- ; Fourth, we send the command and test if it succeded.
- _SCSICmd ;send command to target
-
- move.w #TestUReady,Last_Cmd(A5) ;store command id
- move.w (A7)+,Res(A5) ;test result, was there an error
- bne ToErrorProc ;yes go to error proc
-
- ; Then, we wait for the target device send the Status and
- ; Message bytes. The target device will then release the Mac.
- move.l #10,D0 ;pass number of ticks to wait
- jsr HD_Discon ;proc that handles _SCSIComplete
- tst.w Res(A5) ;SCSI Protocal Error?
- bne ToErrorProc ;yes, go handle display error
-
- ; Lastly, we test the Status byte returned by _SCSIComplete.
- ; This is the SCSI command result code. It will tell us about
- ; the drives condition and if it is ready to be formated.
- move.w #TestUReady,Last_Cmd(A5) ;store command id for
- ;error handling proc
- cmp.w #3,CompStat(A5) ;is there a Write Fault?
- beq ToErrorProc ;yes, go to error handling proc
- cmp.w #4,CompStat(A5) ;is the Drive Not Ready?
- beq ToErrorProc ;yes, go to error handling proc
- cmp.w #20,CompStat(A5) ;is this SCSI command supported?
- beq ToErrorProc ;no, go to error handling proc
-
- jmp EventLoop
-
- ToErrorProc
- jmp ErrorProc
-
- EndProc
-
- ; PROC ParamProc
- ;
- ; We give the user is given dialog box to input parameters used
- ; for formatting drive. We then extract the values from the
- ; TextEdit fields and place the hex values in the appropiate
- ; global variables. All values are checked against maximum
- ; values to make sure they are reasonable.
-
- ParamProc PROC EXPORT
-
- clr.l -(A7) ;space for pointer to dialog
- move.w #ParamRN,-(A7) ;parameter dialog resource numb.
- pea DialogBuff(A5) ;push pointer to dialog storage
- move.l #-1,-(A7) ;dialog on top of all windows
- _GetNewDialog
-
- move.l (A7),DialogPort(A5) ;save pointer to dialog and
- ;leave copy on stack for
- ;call to _SetPort
- _SetPort
-
- lea DialogBuff(A5),A4 ;pass address of dialog record
- jsr DefButton ;make "OK" button the default
- ; Now we set up our dialog box. First two calls to RadioHiLite
- ; have D0=0 as a flag for no radio button to unselect
- ; Register ussage:
- ; D0 Radio button that was selected, now must be unselected
- ; D1 Radio button that was just clicked on; to be selected
- ; D6 Interleave Radio Button that is currently selected
- ; D7 Step Rate Radio Button that is currently selected
- moveq.l #3,D6 ;default interleave = 1:1
- moveq.l #7,D7 ;default step pulse = 3 msec
-
- ; High light default interleave and step pulse radio buttons.
- move.w D6,D1
- clr.w D0
- jsr RadioHiLite
- clr.w D0
- move.w D7,D1
- jsr RadioHiLite
-
-
- NotYet
- clr.l -(A7) ;use standard filter proc function
- pea ButtonHit(A5) ;push address of storage for item#
- _ModalDialog
- move.w ButtonHit(A5),D1 ;move item number to D1
- cmpi.w #2,D1 ;was OK or Cancel selected?
- ble EndDialog ;yes, go close up dialog
- cmpi.w #9,D1 ;was text edit item hit
- bgt NotYet ;yes, loop back for next event
- cmpi.w #6,D1 ;was interleave radio button hit
- bgt StepRate ;no, must be step rate radio button
-
- ; Interleave radio button was selected. Update D6 and select
- ; the correct radio button.
- move.w D6,D0
- move.w D1,D6
- jsr RadioHiLite
- bra.s NotYet
-
- ; Step rate radio button was selected. Update D7 and select
- ; the correct radio button.
- StepRate:
- move.w D7,D0
- move.w D1,D7
- jsr RadioHiLite
- bra NotYet
-
- EndDialog
-
- cmpi.w #2,ButtonHit(A5) ;was "Cancel" selected?
- blt Continue ;no
- bra exit ;yes, so exit
- ; "OK" button selected so we can update the global variables
- ; that contain the step code and the interleave values.
- Continue
- subq.w #2,D6
- move.w D6,Interleave(A5)
- subq.w #7,D7
- move.w D7,StepCode(A5)
-
- ; For each of the TextEdit fields we place the address of the
- ; global variable in A3, the item # in D0 and the maximum value
- ; in D3. We then call ExtractNumb to get the hex, insure that
- ; it is not over the maximum value, and place the hex number in
- ; the global variable.
- lea Heads(A5),A3 ;extract number of heads from
- move.l #10,D0 ;item number 10
- move.l #MaxHeads,D3
- jsr ExtractNumb
-
- lea Cyls(A5),A3 ;extract number of cylinders
- move.l #11,D0 ;from item number 11
- move.l #MaxCylind,D3
- jsr ExtractNumb
-
- lea RedWrtCur(A5),A3 ;extract reduced write current
- move.l #12,D0 ;cylinder from item #12
- move.l Cyls(A5),D3
- jsr ExtractNumb
-
- lea WrtPreComp(A5),A3 ;extract write precompensation
- move.l #13,D0 ;cylinder from item #13
- move.l Cyls(A5),D3
- jsr ExtractNumb
-
-
- Exit
- move.l DialogPort(A5),-(A7) ;pass pointer to Dialog rec
- _CloseDialog ;close dialog box
- jmp EventLoop ;return to event loop
- EndProc
-
- ; PROC EDefectProc
- ;
- ; Here we ask the user to enter the defects that are listed on
- ; the sheet that came with their disk drive. They can enter as
- ; many as 60 defects. Since our dialog box only has room for 12
- ; defects, we ask the user to hit the "More" button if they have
- ; additional defects. We give the user a dialog box when they
- ; cannot enter any more defects.
- ;
- ; Register Ussage:
- ; D0 Index for next item in dialog that is EditText that
- ; we are going to remove a value from
- ; D6 Index for record being input in defect list; index
- ; is byte index of first field in record, not
- ; actual record number
- EDefectProc PROC EXPORT
-
- clr.l BadB_Num(A5) ;clear global for # of defects
-
- ; Clear our defect buffer.
- move.l #MaxBBListLen,D0 ;pass buffer size in D0
- lea BadB_List(A5),A0 ;pass address in A0
- jsr ClearBuff ;go clear buffer
-
-
-
- LoopForMore
- clr.l D6 ;clear buffer record index
-
- clr.l -(A7) ;space for pointer to dialog rec
- move.w #EDefectsRN,-(A7) ;Enter Defects Dialog resource #
- pea DialogBuff(A5) ;pass pointer to dialog storage
- move.l #-1,-(A7) ;make this window on top
- _GetNewDialog ;get dialog
-
- move.l (A7),DialogPort(A5) ;save pointer to dialog and
- ;leave a copy on stack for
- ;call to _SetPort
- _SetPort
-
- lea DialogBuff(A5),A4 ;pass address of dialog record
- jsr DefButton ;outline default button
-
-
- NotYet
- clr.l -(A7) ;use standard filter proc function
- pea ButtonHit(A5) ;place for button hit
- _ModalDialog ;handle dialog events
- cmpi.w #3,ButtonHit(A5) ;is "Cancel" button hit?
- blt EndDialog ;no, "More" or "OK" buttons were hit
- bgt NotYet ;no, not a button, get another event
-
-
- ; User hit "Cancel" button, so clear defect count and return
- ; go close dialog box
- clr.l BadB_Num(A5)
- bra exit
-
- ; We want to close up the dialog, but first we must extract the
- ; defect data that the user has entered.
- EndDialog
- move.l BadB_Num(A5),D6 ;move number of defects into D6
- lsl.l #4,D6 ;multiply by 16 to get byte
- ;index for first field in
- ;next empty record
- lea BadB_List(A5),A0 ;A0 points 1st byte of buffer
-
- AddToBuff
- move.l #3,D0 ;first item is 4, so put 3 in D0
-
- LoopAddBuff
- ; First we extract the cylinder number. We use the ExtractNumb
- ; procedure which takes the address for the result in A3, the
- ; maximum value in D3 and the item number in D0.
-
- addq.l #1,D0 ;increment D0 by 1, next item
- lea CylBBuff(A0,D6.L),A3
- move.l #MaxCylind,D3
- jsr ExtractNumb
-
- ; Next we extract the head number
- addq.l #1,D0
- lea HeadBBuff(A0,D6.L),A3
- move.l #MaxHeads,D3
- jsr ExtractNumb
-
- ; Lastly we extract the Bytes From Index value.
- addq.l #1,D0
- lea BFIBBuff(A0,D6.L),A3
- move.l #MaxBFI,D3
- jsr ExtractNumb
-
- ; Test to see if the cylinder number was 0. If so ignore this
- ; record as it was either empty or invalid. Most controller
- ; cards cannot take defects in track 0.
- tst.l CylBBuff(A0,D6.L) ;is cylinder value valid
- bne IncrCounters ;yes increment counters
-
- ; Otherwise, don't increment counters and next record will
- ; overwrite this one which was invalid.
- cmpi.l #39,D0 ;have we reached the last item
- beq Exit ;yes, go close dialog box
- bra LoopAddBuff ;no, go extract next record
-
- ; Cylinder number is not equal to 0 so this is a valid defect.
-
- IncrCounters
- cmpi.l #(MaxBBs-1)*BadBRecLen,D6 ;is our buffer full
- beq.s Exit ;yes, so exit
-
- add.l #BadBRecLen,D6 ;increment buffer index
- cmpi.l #39,D0
- bne LoopAddBuff
-
- Exit
-
- lsr.l #4,D6 ;byte count/16 = number of defects
- move.l D6,BadB_Num(A5) ;store defect number in global
- move.l DialogPort(A5),-(A7) ;pass pointer to dialog
- _CloseDialog ;close up dialog
-
- cmpi.l #60,BadB_Num(A5) ;are there too many bad blocks
- beq.s NoMoreAlert ;yes, go put up alert
-
- cmpi.l #2,D5 ;did user hit "More" button (#2)
- bne ToEventLoop ;no, so go to event loop
- bra LoopForMore ;yes so put up dialog again
-
- ToEventLoop
- jmp EventLoop
-
- NoMoreAlert
- move.w #134,-(A7) ;get our out of buffer space alert
- clr.l -(A7) ;use standard filter proc function
- _CautionAlert ;use a caution alert
- jmp EventLoop
-
- EndProc
-
- ; PROC FormatProc
- ;
- ; Formating procedure. This is where we sent the drive
- ; parameters in a Mode Select command. We then send the drive
- ; defects with the Format Unit command. And then the drive is
- ; ready to use with a driver installing program.
- FormatProc PROC EXPORT
- IMPORT (HD_Select,HD_Discon,WriteDisk):CODE
-
- ; First we put up a dialog box to make sure the user wants to
- ; format the drive.
-
- ; Make String buffer #1, 1 character long. Then move the hex
- ; value in the low order byte of Addr (the SCSI address of the
- ; target device) into the string buffer and convert it to ascii.
- move.b #1,StrBuff1(A5)
- move.b 1+Addr(A5),1+StrBuff1(A5)
- add.b #$30,1+StrBuff1(A5)
-
- clr.b StrBuff2(A5) ;clear all the other string buffers
- clr.b StrBuff3(A5)
- clr.b StrBuff4(A5)
- pea StrBuff1(A5)
- pea StrBuff2(A5)
- pea StrBuff3(A5)
- pea StrBuff4(A5)
- _ParamText ;substitute String buffer 1 for "^0"
-
- move.w #132,-(A7) ;get format alert dialog box
- clr.l -(A7) ;use standard filter proc function
- _CautionAlert
- cmpi.w #1,(A7)+ ;did user hit cancel?
- bne Exit ;yes, so exit
-
- ; User wants to Zap Drive, so let 'em have it! First we
- ; construct a data block to place parameters that we will send
- ; with the Mode Select command.
- ZapDrive
-
- ; First we clear the data buffer
- lea ParamBuff(A5),A0 ;pass address of buffer
- move.l #ParamBuffLen,D0 ;pass length of buffer
- jsr ClearBuff ;clear buffer
-
- clr.l D0 ;clear D0, used for scratch
- ; Header:
- move.b #8,$3(A0) ;3rd byte = size of descriptor
- ;list
-
- ; Descriptor List:
- move.b #2,$A(A0) ;high byte of sector size ($200)
-
- ; Drive Parameter List:
- move.b #1,$C(A0) ;List Format Code: (1 = soft
- ;sectored drives, 2= hard
- ;sectored drives or
- ;removable media drives)
-
- ; Place word value of cylinder count into buffer. We must do
- ; this as two bytes because the wored in the output buffer is
- ; at an odd address
- move.w 2+Cyls(A5),D0
-
- move.b D0,$E(A0) ;make sure $E(A0) has LSB
- lsr.l #8,D0 ;now move in high byte of word
- move.b D0,$D(A0)
-
- ; Move byte value of head count into buffer.
- move.b 3+Heads(A5),$F(A0)
-
- ; Move word value of Reduced Write Current Cylinder into buffer.
- move.w 2+RedWrtCur(A5),$10(A0)
-
- ; Move word value of Write Precompensation Cylinder into buffer.
- move.w 2+WrtPreComp(A5),$12(A0)
-
- ; Move byte value of Step Pulse Code into Buffer.
- move.b 1+stepcode(A5),$15(A0)
-
- ; Now we send the Mode Select Command and the parameter buffer.
- jsr HD_Select ;get SCSI bus and select drive
- tst.w Res(A5) ;did we succeed?
- bne ToErrorProc ;no, so go to error handling proc
-
- ; Clear command buffer and construct command.
- lea CommandBuff(A5),A0 ;pass address of buffer
- move.l #CBuffLen,D0 ;pass length of buffer
- jsr ClearBuff ;clear command buffer
-
- move.b #ModeSelect,(A0) ;move SCSI OP Code into byte #0
-
- move.b #ModeSelBytesOut,4(A0) ;move # of bytes to transfer
- ;into byte #4
-
- clr.w -(A7) ;space for trap error code
- move.l A0,-(A7) ;pass address of command buffer
- move.w #CommLenS,-(A7) ;pass length of CDB (Command Data
- ;Block), class 0 command, so it
- ;is 6 bytes long
- _SCSICmd ;send command
-
- move.w #ModeSelect,Last_Cmd(A5) ;store command id
-
- move.w (A7)+,Res(A5) ;did command work?
- bne ToErrorProc ;no, go to error handling proc
-
- ; Now we clear the pseudo program buffer and call the procedure
- ; WriteDisk to send the data to the controller card.
- lea PseudoProg(A5),A0 ;pass address of buffer
- move.l #PProgLen,D0 ;pass size of buffer
- jsr ClearBuff ;clear buffer
-
- lea ParamBuff(A5),A1 ;pass address of data buffer
- move.l #ModeSelBytesOut,D0 ;pass # of bytes to transfer
- jsr WriteDisk ;send data
-
- move.l #10,D0 ;pass number of ticks to wait
- jsr HD_Discon
- tst.w Res(A5) ;SCSI Protocal Error?
- bne ToErrorProc
- move.w #ModeSelect,Last_Cmd(A5)
- cmp.w #$4,CompStat(A5) ;is the Drive Not Ready?
- beq ToErrorProc ;yes, go to error handling proc
- cmp.w #$24,CompStat(A5) ;Was a bad parameter passed to
- ;the controller?
- beq ToErrorProc ;yes, go to error handling proc
-
- jsr HD_Select ;go get control of bus and
- ;select device
- tst.w Res(A5) ;did we succeed
- bne ToErrorProc ;no, go to error proc
-
- ; Next, clear the buffer where we will assemble the CDB (Command
- ; Data Block).
- lea CommandBuff(A5),A0 ;pass address of buffer
- move.l #CBuffLen,D0 ;pass size of buffer
- jsr ClearBuff ;clear buffer
-
-
- move.b #FormatUnit,(A0) ;move op code into first byte
- move.b 1+Interleave(A5),4(A0) ;move byte value of inter
- ;leave into byte 4
-
- tst.l BadB_num(A5) ;see if there are disk defects
- beq NoDefects ;no, skip ahead
- add.b #$1C,1(A0) ;place flags to tell controller
- ;that defects are coming
- ; Call OutBuff to format defects so they can be read by
- ; controller card.
- jsr OutBuff
-
- NoDefects
- clr.w -(A7) ;space for trap error code
- move.l A0,-(A7) ;pass address of CDB
- move.w #CommLenS,-(A7) ;class 0 command so pass length
- ;of 6 bytes
- _SCSICmd ;send command
-
- move.w #FormatUnit,Last_Cmd(A5) ;store command id
-
- move.w (A7)+,Res(A5) ;did _SCSICmd produce an error
- bne ToErrorProc ;yes, go to error handling proc
-
- ; If we are sending any info on disk defects, prepare buffer for
- ; pseudo program and pass count bytes and address to sending
- ; procedure.
- tst.l BadB_num(A5) ;are we sending any defect data?
- beq NoPseudoProg ;no, skip the next section
-
- ; Clear pseudo program buffer.
- lea PseudoProg(A5),A0 ;pass address of buffer
- move.l #PProgLen,D0 ;pass length of buffer
- jsr ClearBuff ;clear buffer
-
- ; Pass address of data, and number of bytes to be transfered. A0
- ; still contains the address of the pseudo program buffer.
- lea BadB_Out(A5),A1
- move.l BadB_Num(A5),D0 ;move number of defects to D0
- lsl.l #3,D0 ;multiply by 8 (8 bytes/defect)
- addq.l #4,D0 ;add 4 bytes for header
- jsr WriteDisk ;send info on defects
-
- NoPseudoProg
- move.l #MaxTicks,D0 ;pass number of ticks to wait
- jsr HD_Discon
- tst.w Res(A5) ;SCSI Protocal Error?
- bne ToErrorProc ;yes, go to error handling proc
-
- ; Test Status byte from SCSI command to see if we passed a bad
- ; parameter or if there is a defect on track 0.
- move.w #FormatUnit,Last_Cmd(A5) ;update command id for
- ;error handling proc
- cmp.w #$24,CompStat(A5) ;Was a bad parameter passed to
- ;the controller?
- beq ToErrorProc ;yes, go to error proc
- jmp EventLoop
-
- Exit
- jmp EventLoop
-
- ToErrorProc
- jmp ErrorProc
-
- EndProc
-
- ; PROC ResetProc
- ;
- ; This procedure is called from the menu handling routine. It
- ; acts as glue between the menu handling code and the reset
- ; subroutine and allows us to use the reset subroutine elsewhere
- ; (like in SelAddrProc).
- ResetProc PROC EXPORT
- IMPORT (ResetDisk):CODE
-
- jsr ResetDisk ;go reset SCSI bus
- tst.w Res(A5) ;test result
- bne ToErrorProc ;if error go to error handling proc
- jmp EventLoop ;else return to event loop
- ToErrorProc
- jmp ErrorProc
- EndProc
-
- ; PROC WriteDisk
- ;
- ; Procedure wor transfering data to the controller. This
- ; routine uses a pseudo program which contains a simple loop of
- ; three instructions. This transfer could have been accomplished
- ; using only the first and the last instruction if we had put
- ; the transfer count that is passed in D0 into the second
- ; parameter of the first command. It would look exactly the
- ; same if it were being used for a read, except the _SCSIWrite
- ; trap would be replaced with _SCSIRead. Refer to IM volume IV
- ; for info on the Pseudo instructions. Note each instruction is
- ; a word followed by two longword parameters. SCSTOP must be
- ; the last instruction. Address of pseudo buffer is passed in
- ; A0. Address of p_buff is passed in A1. Transfer count is
- ; passed in D0.
- WriteDisk PROC ENTRY
- movem.l D0-D2/A0-A1,-(SP) ;save registers
-
- ; First command moves bytes to given address
- move.w #SCINC,(A0)
- move.l A1,2(A0) ;address to be moved to or from
- move.l #1,6(A0) ;transfer count in bytes
-
- ; Second command is loop
- move.w #SCLOOP,10(A0)
- move.l #-10,12(A0) ;rel addr
- move.l d0,16(A0) ;loop count
-
- ; Third command = stop, no parameters
- move.w #SCSTOP,20(A0)
-
- clr.w -(SP) ;space for trap result code (OSErr)
- move.l A0,-(SP) ;address of pseudo program
-
- _SCSIWrite
- move.w (SP)+,Res(A5) ;store result
- move.w #Write,Last_Cmd(A5) ;store code for type of SCSI
- ;command
-
- movem.l (SP)+,D0-D2/A0-A1 ;restore registers
- rts
- ENDPROC
-
- ; PROC HD_Select
- ;
- ; HD_Select tries to get control of the SCSI bus. If it does,
- ; it then selects the device whose address is in Addr(A5).
-
- HD_Select PROC ENTRY
- IMPORT CountOff:CODE
- movem.l D0-D2/A0-A1,-(A7) ;save regs on stack
-
- clr.w -(A7) ;space for result code
- _SCSIGet ;reserve the bus for our use
-
- move.w (A7)+,Res(A5) ;store result code
- beq.s ok ;go to ok2 if we succeeded
- move.w #Get,Last_Cmd(A5) ;else, store the last command
- bra.s exit ;and return
-
- ok
- clr.w -(A7) ;space for result code
- move.w Addr(A5),-(A7) ;load SCSI address of hard disk
- _SCSISelect ;select device
-
- move.w (A7)+,Res(A5) ;store result code
- move.w #Select,Last_Cmd(A5) ;store last command
-
- exit
- movem.l (A7)+,D0-D2/A0-A1 ;restore registers
- rts
- ENDPROC
-
-
- ; PROC HD_Discon
- ;
- ; Here we complete a SCSI command. We tell the Mac how long to
- ; wait for the target device on the SCSI bus to signal that the
- ; command has completed. This procedure receives the number of
- ; ticks to wait in D0.
- HD_Discon PROC ENTRY
-
- movem.l D0-D2/A0-A1,-(A7) ;save regs on stack
-
- clr.w CompStat(A5)
- clr.w CompMsg(A5)
-
- clr.w -(A7) ;space for result code
- pea CompStat(A5) ;_SCSIComplete Status
- pea CompMsg(A5) ;_SCSIComplete Message
- move.l D0,-(A7) ;number of ticks to wait for
- ;completion of the last
- ;SCSI command
- _SCSIComplete
- move.w (A7)+,Res(A5) ;store result code
- move.w #Complete,Last_Cmd(A5) ;store last command
- movem.l (A7)+,D0-D2/A0-A1 ;restore registers
- rts
- ENDPROC
-
- ; PROC InitGlobals
- ;
- ; Initialize the globals used to store information about the
- ; hard disk. Set all values to zero
- InitGlobals PROC EXPORT
-
- clr.w Heads(A5)
- clr.w Cyls(A5)
- clr.w WrtPreComp(A5)
- clr.w RedWrtCur(A5)
- clr.w Interleave(A5)
- clr.w StepCode(A5)
- clr.l Addr(A5)
-
- clr.l BadB_Num(A5)
-
- rts
- ENDPROC
-
- ; PROC ResetDisk
- ;
- ; This procedure resets the SCSI bus. It has a one second delay
- ; after the reset because the CDC Wren III drives take more than
- ; 3/4 of a second to completely reset. Other drives may need
- ; longer delays after the reset.
- ResetDisk PROC EXPORT
-
- movem.l D0-D2/A0-A1,-(A7) ;save the registers
- clr.w -(A7) ;space for result code
- _SCSIReset ;reset the bus
- move.w (A7)+,Res(A5) ;store results
- beq.s ok1 ;go to ok1 if we succeeded
- move.w #Reset,Last_Cmd(A5) ;else command code for error Msg
- rts
-
- ok1
- move.l #60,D0 ;D0 = number of ticks to wait
- jsr CountOff ;jst to delay routine
-
- movem.l (A7)+,D0-D2/A0-A1 ;restore the registers
- rts
- ENDPROC
-
- END